home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / 80x0393.zip / TIMER.ASM < prev    next >
Assembly Source File  |  1993-06-20  |  7KB  |  170 lines

  1. ;***************************************
  2. ;* Sample code to change the timer value
  3. ;* Written by Dave M. Walker
  4. ;*
  5. ;* Frequency for 8253 = 4.77MHz/4 = 1192500
  6. ;* Default BIOS countdown = 65536 = 18.2/sec
  7. ;***************************************
  8.                 IDEAL
  9.                 MODEL   TINY
  10.  
  11.                 CODESEG
  12.                 ORG     0100h
  13. Start:          jmp     Begin
  14.  
  15. PSPlen          equ     0100h                   ;Used to calc. TSR length
  16.  
  17. VideoSeg        equ     0b800h                  ;For color
  18. ;VideoSeg       equ     0b000h                  ;For mono
  19.  
  20. NewCount        equ     582                     ;2048/sec
  21.  
  22. CmdReg8253      equ     43h                     ;8253 Command Register port
  23. TickChannel     equ     40h                     ;8253 System Timer channel
  24. TickInt         equ     08h                     ;IRQ0 = INT 08
  25.  
  26. Warning$        db      13,10
  27.                 db      'WARNING!  This program reprograms the 8253'
  28.                 db      ' timer chip.  If the system is running under a'
  29.                 db      ' multitasker, the system may hang or behave'
  30.                 db      ' abnormally.',13,10,'Continue (Y/N)? $'
  31.  
  32. Begin:          mov     dx,OFFSET Warning$      ;Warn user that we're going
  33.                 mov     ah,9                    ;  to mess with the timer
  34.                 int     21h
  35. KeyLoop:        mov     ah,8                    ;Get Y/N response
  36.                 int     21h
  37.                 xor     ah,ah
  38.                 or      al,al
  39.                 jne     GotKey
  40.                 mov     ah,8                    ;Handle extended keycode
  41.                 int     21h
  42.                 xor     ah,ah                   ;Make it negative
  43.                 neg     ax
  44.  
  45. GotKey:         cmp     ax,3                    ; ^C = Abort
  46.                 je      Abort
  47.                 cmp     ax,27                   ;ESC = Abort
  48.                 je      Abort
  49.                 cmp     ax,78                   ;"N" = Abort
  50.                 je      Abort
  51.                 cmp     ax,110                  ;"n" = Abort
  52.                 je      Abort
  53.                 cmp     ax,89                   ;"Y" = Continue
  54.                 je      Continue
  55.                 cmp     ax,121                  ;"y" = Continue
  56.                 je      Continue
  57.                 mov     dl,7                    ;Invalid response - beep!
  58.                 mov     ah,2
  59.                 int     21h
  60.                 jmp     KeyLoop                 ;Try again
  61.  
  62. Abort:          mov     ax,4c00h                ;Back to DOS
  63.                 int     21h
  64.  
  65. Continue:       mov     al,TickInt              ;Get old timer vector
  66.                 mov     ah,35h
  67.                 int     21h
  68.                 mov     [OldSeg],es             ;Save it
  69.                 mov     [OldOfs],bx
  70.  
  71.                 mov     dx,OFFSET NewISR        ;Set new timer vector
  72.                 mov     ah,25h                  ;  (DS already correct)
  73.                 int     21h
  74.                 mov     al,36h                  ;Reprogram 8253 countdown
  75.                 out     CmdReg8253,al           ;  register
  76.                 mov     ax,NewCount
  77.                 out     TickChannel,al          ;Send LSB
  78.                 mov     al,ah
  79.                 out     TickChannel,al          ;Send MSB
  80.  
  81.                 mov     dx,Paragraphs           ;Calculate size of routine
  82.                 mov     ax,3100h                ;TSR with errorlevel 0
  83.                 int     21h
  84.  
  85. ;* New timer ISR and data
  86.  
  87. SlowCounter     db      4                       ;Counter for generating
  88.                                                 ;  1/512 sec interval
  89. BIOSCounter     dw      0                       ;Counter for BIOS's handler
  90.  
  91. LABEL           OldVector DWORD                 ;BIOS's timer vector
  92. OldOfs          dw      ?                       ;  Offset portion
  93. OldSeg          dw      ?                       ;  Segment portion
  94.  
  95. NewISR:         call    FastHook                ;Fast routine always called
  96.                 dec     [cs:SlowCounter]        ;If --counter != 0
  97.                 jne     SkipSlow                ;  not time yet...
  98.                 call    SlowHook                ;else call the slow routine
  99.                 mov     [cs:SlowCounter],4      ;  and reset counter
  100. SkipSlow:       add     [cs:BIOSCounter],NewCount ;Update BIOS counter
  101.                 jno     SkipBIOS                ;If no overflow, skip
  102.                 pushf                           ;else simulate a clock tick
  103.                 call    [DWORD cs:OldVector]    ;  interrupt
  104.                 iret                            ;BIOS already ACK'ed the INT
  105.  
  106. SkipBIOS:       push    ax
  107.                 mov     al,20h                  ;Acknowledge the INT by
  108.                 out     20h,al                  ;  resetting the 8259 PIC
  109.                 pop     ax
  110.                 iret
  111.  
  112. ;* This is the fast interrupt procedure.  All registers except the flags
  113. ;* MUST be preserved, including segment registers.  The ONLY register that
  114. ;* has a known value at the beginning of this procedure is CS.
  115.  
  116. FastNum         dw      0                       ;Counter
  117.  
  118. FastHook:       push    dx di                   ;Save regs
  119.  
  120.                 mov     dx,[cs:FastNum]         ;Get our counter
  121.                 inc     [cs:FastNum]            ;Update it
  122.                 mov     di,(0)*160+(79)*2       ;Right edge at (0,79)
  123.                 call    DispNum                 ;Display it
  124.  
  125.                 pop     di dx
  126.                 ret
  127.  
  128. ;* This is the slow interrupt procedure.  Same rules apply.
  129.  
  130. SlowNum         dw      0                       ;Counter
  131.  
  132. SlowHook:       push    dx di                   ;Save regs
  133.  
  134.                 mov     dx,[cs:SlowNum]         ;Get our counter
  135.                 inc     [cs:SlowNum]            ;Update it
  136.                 mov     di,(0)*160+(74)*2       ;Right edge at (0,74)
  137.                 call    DispNum                 ;Display it
  138.  
  139.                 pop     di dx
  140.                 ret
  141.  
  142. DispNum:        push    ax cx es
  143.  
  144.                 mov     ax,VideoSeg             ;Point ES to video
  145.                 mov     es,ax
  146.                 mov     ah,0fh                  ;Attribute for display
  147.                 mov     cx,0404h                ;Set CL=4 for shifts, and
  148.                                                 ;  CH=4 for loop counter
  149.                 std                             ;Going backwards!
  150. DispNumLoop:    call    DispDigit               ;Display a digit
  151.                 shr     dx,cl                   ;Rotate for next digit
  152.                 dec     ch
  153.                 jnz     DispNumLoop             ;Do it four times
  154.  
  155.                 pop     es cx ax
  156.                 ret
  157.  
  158. DispDigit:      mov     al,dl                   ;Get low byte
  159.                 and     al,0fh                  ;Keep only low nybble
  160.                 add     al,'0'                  ;Convert to hex ASCII
  161.                 cmp     al,'9'
  162.                 jbe     NotLetter
  163.                 add     al,7                    ;Adjust for letter
  164. NotLetter:      stosw                           ;Store digit/attribute
  165.                 ret
  166.  
  167. Paragraphs      =       ($-Start+PSPlen+15) SHR 4
  168.  
  169.                 END     Start
  170.